﻿using Lcygcc.Infrastructure.Core;
using Lcygcc.Infrastructure.Logs;
using Lcygcc.Infrastructure.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Lcygcc.Domain.TaskService
{
    public class AutoTaskThread : IAutoTaskThread
    {
        //private List<RequestArgs> mRequestArgsList = new List<RequestArgs>();
        /// <summary>
        /// 定时任务处理线程
        /// </summary>
        private Thread ThreadTaskJob = null;

        /// <summary>
        /// 定时创建任务线程
        /// </summary>
        private Thread ThreadCreateTask = null;

        /// <summary>
        /// 定时上云推送线程
        /// </summary>
        private Thread ThreadCloudTask = null;

        /// <summary>
        /// 记录任务最后执行时间
        /// </summary>
        private Dictionary<string, DateTime> dicLastExcuteTime = new Dictionary<string, DateTime>();

        /// <summary>
        /// 待处理任务
        /// </summary>
        private List<BaseTaskService> mTaskJobList = new List<BaseTaskService>();

        public void Start()
        {
            //创建任务
            ThreadHelper.StartBgThread(ref ThreadCreateTask, new ParameterizedThreadStart(CreateTask), null, true);

            //执行任务
            ThreadHelper.StartBgThread(ref ThreadTaskJob, new ParameterizedThreadStart(TaskJob), null, true);

            //上云推送线程
            ThreadHelper.StartBgThread(ref ThreadCloudTask, new ParameterizedThreadStart(CloudTask), null, true);
        }

        /// <summary>
        /// 定时任务
        /// </summary>
        /// <param name="state"></param>
        private void TaskJob(object state)
        {
            Logger.Info("----TaskJob定时任务处理线程启动完成----");
            while (true)
            {
                try
                {
                    if (mTaskJobList == null || mTaskJobList.Count <= 0)
                    {
                        Thread.Sleep(1000);
                    }
                    else
                    {
                        var mTaskJob = mTaskJobList.OrderBy(x => x.RequestArgs.ExcuteTime).FirstOrDefault();
                        Logger.Info(string.Format("----TaskJob出列---：任务{0}出列，执行时间：{1}，剩余执行数量：{2}", mTaskJob.RequestArgs.ServiceID, mTaskJob.RequestArgs.ExcuteTime, mTaskJobList.Count));
                        mTaskJob.TimerSend();
                        mTaskJobList.RemoveAt(0);
                    }
                    Thread.Sleep(100);
                }
                catch (Exception ex)
                {
                    Logger.Error("----TaskJob定时任务处理线程异常：",ex);
                    Thread.Sleep(1000);
                }
            }
        } 

        /// <summary>
        /// 定时任务
        /// </summary>
        /// <param name="state"></param>
        private void CreateTask(object state)
        {
            Logger.Info("----定时任务加载线程启动完成----");
            DateTime startTime = DateTime.Now;
            DateTimeOffset utcNow = DateTime.Now;
            List<RequestArgs> mRequestArgsList = new List<RequestArgs>();
            mRequestArgsList = EngineContext.Current.Resolve<ITaskJobManager>().RequestArgsList;
            while (true)
            {
                if (mRequestArgsList.Count == 0)
                {
                    Thread.Sleep(1000);
                }
                foreach (var args in mRequestArgsList)
                {
                    try
                    {
                        utcNow = SystemTime.UtcNow();
                        CronExpression expression = new CronExpression(args.Cron);
                        startTime = DateTime.Parse(expression.GetNextValidTimeAfter(utcNow).ToString());

                        if (!dicLastExcuteTime.ContainsKey(args.ServiceID))
                        {
                            dicLastExcuteTime.Add(args.ServiceID, startTime);
                        }
                        //在执行时间内
                        if ((DateTime.Now - dicLastExcuteTime[args.ServiceID]).TotalMilliseconds > 0)
                        {
                            string strMessage = "";
                            RequestArgs tempArgs = mTaskJobList.Where(x => x.RequestArgs.ServiceID.Contains(args.ServiceID)).Select(x => x.RequestArgs).FirstOrDefault();
                            if (tempArgs == null)
                            {
                                BaseTaskService baseTaskService = new BaseTaskService();
                                baseTaskService.RequestArgs = args;
                                baseTaskService.RequestArgs.ExcuteTime = dicLastExcuteTime[args.ServiceID];
                                mTaskJobList.Add(baseTaskService);
                                strMessage = string.Format("----CreateTask入列---：任务{0}加入计划队列，执行时间：{1}，剩余执行数量：{2}", args.ServiceID, startTime, mTaskJobList.Count);
                            }
                            else
                            {
                                strMessage = string.Format("----CreateTask入列---：任务{0}已在待处理队列中", args.ServiceID);

                            }
                            Logger.Info(strMessage);
                            dicLastExcuteTime[args.ServiceID] = startTime;
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.Error("----定时任务加载线程启动异常----", ex);
                        Thread.Sleep(1000);
                    }
                }


                Thread.Sleep(100);
            }
        }

        /// <summary>
        /// 上云推送
        /// </summary>
        /// <param name="state"></param>
        private void CloudTask(object state)
        {
            while (true)
            {
                try
                {
                    var task = new BaseTaskService();
                    task.RequestArgs = new RequestArgs();
                    task.RequestArgs.ServiceID = "JKCloudChannel";
                    task.RequestArgs.AdapterMethod = "SendToCloud";
                    task.CloudSend();
                }
                catch (Exception ex)
                {
                    Logger.Error("----上云推送异常----", ex);
                    Thread.Sleep(1000);
                }
                Thread.Sleep(1000);
            }
        }
    }
}
